/*
 * Esta clase dibuja el tablero y reacciona a los cambios.
 */
package sudoku.Vista;

import java.awt.Color;
import java.awt.GridLayout;
import java.util.Observable;
import java.util.Observer;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import sudoku.Controlador.SudokuControlador;
import sudoku.Extras.Tripla;
import sudoku.Modelo.Juego;

/**
 *
 * @author User
 */
public class SudokuPanel extends JPanel implements Observer {
    private Color COLOR_CANDIDATO = new Color(102, 153, 25);
    private Campo[][] campos;       // Arreglo de Campos.
    private JPanel[][] paneles;      // Paneles que contienen a los campos.
    
    /**
     * Crea nuevo sudoku panel.
     */
    public SudokuPanel() {
        super(new GridLayout(3,3));
        
        paneles = new JPanel[3][3];
        for (int y = 0; y < 3; y++) {
            for (int x = 0; x < 3; x++) {
                paneles[y][x] = new JPanel(new GridLayout(3, 3));
                paneles[y][x].setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
                add(paneles[y][x]);
            }
        }
        
        campos = new Campo[9][9];
        for (int y = 0; y < 9; y++) {
            for (int x = 0; x < 9; x++) {
                campos[y][x] = new Campo(x, y);
                paneles[y / 3][x / 3].add(campos[y][x]);
            }
        }
    }
    
    /**
     * Metodo llamado cuando el modelo envia notificaciones de actualizacion.
     *
     * @param o     El modelo.
     * @param arg   La accion.
     */
    public void update(Observable o, Object arg) {
        switch ((String)arg) {
            case "Solucionar": 
                setSolucionar((Juego)o);
                break;
            case "Nuevo":
            case "Cargar":
                setJuego((Juego)o);
                break;
            case "Chequear":
                setChequeoJuego((Juego)o);
                break;
            case "NumeroSeleccionado":
            case "Candidatos":
            case "Ayuda":
                setCandidatos((Juego)o);
                break;   
        }
    }
      
    /**
     * Setea los campos de acuerdo al juego dado.
     *
     * @param juego  Juego a ser seteado.
     */
    public void setJuego(Juego juego) {
        for (int y = 0; y < 9; y++) {
            for (int x = 0; x < 9; x++) {
                campos[y][x].setBackground(Color.WHITE);
                if (juego.mIGuardado[y][x].getSeg() == 1){
                    campos[y][x].setNumero(juego.getNumero(x, y), true);
                }else{
                    campos[y][x].setNumero(juego.getNumero(x, y), false);
                }
            }
        }
        this.setEnabled(true);
    }

    /**
     * Setea campos validos de acuerdo al juego dado.
     *
     * @param juego Juego Corriente.
     */
    private void setChequeoJuego(Juego juego) {
        for (int y = 0; y < 9; y++) {
            for (int x = 0; x < 9; x++) {
                campos[y][x].setBackground(Color.WHITE);
                if((campos[y][x].getForeground().equals(Color.BLUE)) && (!campos[y][x].getText().equals(""))) {
                    campos[y][x].setBackground(juego.esValida(x, y) ? Color.GREEN : Color.RED);
                }
            }
        }      
    }

    /**
     * Muestra los candidatos de acorde al juego dado.
     *
     * @param juego Juego Corriente.
     */
    private void setCandidatos(Juego juego) {
        for (int y = 0; y < 9; y++) {
            for (int x = 0; x < 9; x++) {
                campos[y][x].setBackground(Color.WHITE);
                if (juego.conAyuda() && juego.esCandidatoNumSeleccionado(x, y))
                    campos[y][x].setBackground(COLOR_CANDIDATO);
            }
        }
    }
    
    private void setSolucionar(Juego juego){
        Tripla[][] juegoTemp = juego.getJuegoTemporal();
        for (int y = 0; y < 9; y++) {
            for (int x = 0; x < 9; x++) {
                campos[y][x].setBackground(Color.GRAY);
                if (juegoTemp[y][x].getPri()!=0 && juegoTemp[y][x].getSeg()==0) {
                    campos[y][x].setNumero(juegoTemp[y][x].getTer(), false);
                } 
                else{
                    campos[y][x].setNumero(juegoTemp[y][x].getTer(), true);
                }
            }
        }
        this.setEnabled(false);
    }

    /**
     * Agrega el controlador a todos los subpaneles.
     *
     * @param sudokuControlador  Controlador para controlar las acciones de usuario.
     */
    public void setController(SudokuControlador sudokuControlador) {
        for (int y = 0; y < 3; y++) {
            for (int x = 0; x < 3; x++)
                paneles[y][x].addMouseListener(sudokuControlador);
        }
    }
     
}
